package usi.ch.onto.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import usi.ch.onto.common.StringUtils;
import usi.ch.onto.lucene.scoring.KeyTermExtractor;
import usi.ch.onto.yago.ExportResults;
import usi.ch.onto.yago.MatchingStrings;
import usi.ch.onto.yago.MatchingStrings.TypeOfMatching;
import usi.ch.onto.yago.SynonymLookup;
import usi.ch.onto.yago.TaxonomyBuilder;
import usi.ch.onto.yago.TaxonomyBuilder.OriginTable;


public class MainYagoMatching {
	private static final String INDEXES = "../yagoaida_resources/bigindex";
	private static final String FALSELIST = "../yagoaida_resources/list_maui1.txt";
	
	
	private static final String DESTINATION_DIR = "C:\\Users\\Aida\\Desktop\\yago\\pyago\\facts";

	//Params for the export of file with synonyms that originate from the 
	//no match list
	private static final String SYNONYM_DESTINATION_FILE = DESTINATION_DIR + "\\synonyms.txt";
	private static final int SYNONYM_INITIAL_COUNT = 10000;
	
	public static void main(String[] args) throws Exception {		
		long start = System.currentTimeMillis();

		firstPhase();
		
		secondPhase();
		
		//this phase finds the the types in subclass and stored them in Subclassresults 
		//NOT NEEDED now
		//subclassPhase();
		
		
		//createTaxonomy();
		
		//exportPhase();
		
		System.out.println("finished process. took " + (System.currentTimeMillis() - start) / 1000.0 + " s" );
	}

	/**
	 * @deprecated
	 * @throws Exception
	 */
	private static void subclassPhase() throws Exception{
		MatchingStrings match = new MatchingStrings(new ArrayList<String>());
		match.subclassPhase();
	}	
	
	private static void createTaxonomy() throws Exception {
		System.out.print("start taxonomy creation...");
		//create tree for subclassResults		
		TaxonomyBuilder tax = new TaxonomyBuilder("subclass", OriginTable.subclassResults, "taxonomy", false);
		tax.createTree();
		
		//create tree for tabTypes
		tax = new TaxonomyBuilder("subclass", OriginTable.tabTypes, "taxonomy", false);
		tax.createTree();
		
		//DELETE entries with less then xxx count
		//tax.deleteAllEntriesWithLessThanOrEqual(count);
		
		tax.insertSuperClassesOfExistingClassesInTree();
		
		System.out.println("done");
	}
	
	private static void exportPhase() throws Exception{
		ExportResults export = new ExportResults();
		
		export.exportNormalTable("tab1", DESTINATION_DIR); 
		export.exportNormalTable("tab2", DESTINATION_DIR);
		export.exportNormalTable("tab1or2", DESTINATION_DIR);
		export.exportNormalTable("tabext", DESTINATION_DIR);
		export.exportNormalTable("subclass", DESTINATION_DIR);
		
		//TODO
		export.exportTableTaxonomy(DESTINATION_DIR + "\\taxonomy");
		
	}
	
	private static void firstPhase() throws Exception{
		//first matching pass 
		System.out.print("Starting first pass...");
		List<String> noMatches = processListTerms(getFalseList() ); //getIndexTerms()
		System.out.println("done");
		
		System.out.print("matching means and processing...");
		//get list of terms not matched in the means and process it again
		MatchingStrings match = new MatchingStrings(noMatches);
		List<String> newTermsToMatch = match.matchTerms("tab1or2", TypeOfMatching.means);
		noMatches = processListTerms(newTermsToMatch);
		System.out.println("done");
		
		System.out.println("get synonyms and processing...");
		//get synonyms from the new list of no matches and process it again 
		newTermsToMatch = SynonymLookup.getSynonymsFromList(noMatches);
		//export to file file with synonyms
		System.out.println("export list of nomatches and their synonyms to " + SYNONYM_DESTINATION_FILE);
		ExportResults.exportSynonyms(
				SYNONYM_DESTINATION_FILE
				, SYNONYM_INITIAL_COUNT
				, noMatches
				, newTermsToMatch
				, true);
		
		noMatches = processListTerms(newTermsToMatch);
		
		//TODO export list of noMatches
		System.out.println("dumping the final list of no matches");
		for(String item : noMatches){
			System.out.println(item);
		}		
	}
	
	private static void secondPhase() throws Exception{
		List<String> emptyList = new ArrayList<String>();
		//we dont need a list with terms for this phase
		MatchingStrings match = new MatchingStrings(emptyList);
		match.phase2();
	}
	
	private static void test() throws Exception{
		List<String > terms = SynonymLookup.getSynonymsFromList(getFalseList());
		
		throw new Exception("end testing");
	}
	
	private static List<String> processListTerms(List<String> listTerms) throws Exception {
		MatchingStrings match = new MatchingStrings(listTerms);
		List<List<String>> listOfListsNoMatches = new ArrayList<List<String>>();
		listOfListsNoMatches.add(match.matchTerms("tab1", TypeOfMatching.arg1));
		listOfListsNoMatches.add(match.matchTerms("tab2", TypeOfMatching.arg2));
		listOfListsNoMatches.add(match.matchTerms("tab1or2", TypeOfMatching.arg1or2));	

		//we set the list of terms that were no match in the entities and set it to 
		//be searched in subclass
		List<String> noMatchInEntities = StringUtils.getIntersectionList(listOfListsNoMatches);
		match.setListTerms(noMatchInEntities);
		
		//returns list of no match in subclass 
		//at this point the terms left did not match entities and subclass
		return match.matchTerms("subclass", TypeOfMatching.subclass);	
	}


	/**
	 *Reads the term list from the index
	 * 
	 * @return termlist - list with frequent terms in index
	 */
	public static List<String> getIndexTerms() throws IOException {
		KeyTermExtractor itReader = new KeyTermExtractor();

		itReader.retrieveTerms(new File(INDEXES));
		ArrayList<String> termlist = itReader.getTermList();
		return termlist;
	}
	
	public static List<String> getFalseList()throws IOException{
		ArrayList<String>falseList = new ArrayList<String>();
		File file = new File(FALSELIST);
		BufferedReader reader = null;
		
		try {
			reader = new BufferedReader(new FileReader(file));
			String text = null;
			while((text = reader.readLine())!= null){
				if (text.isEmpty() == false)
					falseList.add(text);
			}
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally{
			try {
				if (reader != null){
					reader.close();
				}
			} catch (IOException e2) {
				e2.printStackTrace();
			}
		}
		return falseList;
	}
}
